import os
import tkinter as tk
from tkinter import filedialog
import subprocess
from tkinter.ttk import Treeview
from pathlib import Path
import ctypes
from datetime import datetime


def openPath(path: str):
    if os.name == 'nt':
        os.startfile(path)
    else:
        opener = 'open' if os.name == 'mac' else 'xdg-open'
        subprocess.call([opener, path])


class App(tk.Tk):
    def __init__(self):
        super().__init__()
        ctypes.windll.shcore.SetProcessDpiAwareness(1)
        scale_factor = ctypes.windll.shcore.GetScaleFactorForDevice(0)
        scale = scale_factor / 100
        self.tk.call('tk', 'scaling', scale)
        self.geometry('{:.0f}x{:.0f}+{}+{}'.format(scale*800, scale*600, 500, 200))
        self.title("目录索引工具")
        frame = tk.Frame(self)
        frame.pack(fill=tk.BOTH, expand=1)
        self.treeView = Treeview(frame, show="tree headings")
        self.treeView["columns"] = ("mtime",)
        self.treeView.column('#0', stretch=1)
        self.treeView.column('mtime', stretch=0)
        self.treeView.heading("#0", text="文件名")
        self.treeView.heading("mtime", text="修改时间")
        self.treeView.pack(side=tk.LEFT, fill=tk.BOTH, expand=1)
        self.treeView.bind('<Double-1>', self.onDoubleClick)

        scrollbar = tk.Scrollbar(frame, orient="vertical")
        scrollbar.config(command=self.treeView.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.treeView.config(yscrollcommand=scrollbar.set)

        browseButton = tk.Button(self, text="浏览文件夹", command=self.browseFolder)
        browseButton.pack(pady=10)

        self.searchEntry = tk.Entry(self)
        self.searchEntry.pack(side=tk.TOP, fill=tk.X)
        searchButton = tk.Button(self, text="关键字检索", command=self.search)
        searchButton.pack(pady=10)

    def browseFolder(self):
        folder_selected = filedialog.askdirectory()
        if folder_selected == "":
            return
        self.clearTreeView()
        path = Path(folder_selected)
        self.buildTreeView(path)


    def search(self):
        folder_selected = filedialog.askdirectory()
        if folder_selected == "":
            return
        self.clearTreeView()
        keyword = self.searchEntry.get()
        path = Path(folder_selected)
        self.buildTreeView(path, keyword=keyword)


    def buildTreeView(self, root: Path, parent="", keyword=""):
        searched = False  # 当前目录是否存在符合条件的文件,用于检索模式下递归删除空文件夹和无检索结果的文件夹的树节点
        for path in root.iterdir():
            if path.is_dir():
                item = self.treeView.insert(parent, 'end', text='▶'+path.name, tags=(path,), open=True)
                s = self.buildTreeView(path, parent=item, keyword=keyword)
                if s:
                    searched = True
                elif keyword:
                    self.treeView.delete(item)
            elif keyword in path.name.lower():
                searched = True
                time = datetime.fromtimestamp(path.stat().st_mtime).strftime('%Y-%m-%d')
                self.treeView.insert(parent, 'end', text=path.name, tags=(path,), values=(time,))
        return searched

    def clearTreeView(self):
        for item in self.treeView.get_children():
            self.treeView.delete(item)

    def onDoubleClick(self, event):
        item = self.treeView.focus()
        if not item:
            return
        path = Path(self.treeView.item(item)["tags"][0])
        if path.is_dir():
            return
        openPath(path.parent)


if __name__ == '__main__':
    app = App()
    app.mainloop()